package com.lvsc.sdaplacefinder.services;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;

import org.apache.commons.io.FilenameUtils;

import com.lvsc.sdaplacefinder.dao.DataServiceFactory;
import com.lvsc.sdaplacefinder.models.Place;
import com.sun.jersey.core.header.FormDataContentDisposition;
import com.sun.jersey.multipart.FormDataParam;

@Path("upload")
public class UploadService {

	public static final String UPLOAD_USER_DIR = "c:\\placefinder";

	@POST
	@Path("{placeId}")
	@Consumes(MediaType.MULTIPART_FORM_DATA)
	public Response uploadFile(
			@FormDataParam("uploadedfile") InputStream uploadedInputStream,
			@FormDataParam("uploadedfile") FormDataContentDisposition fileDetail,
			@PathParam("placeId") Long placeId) {

		File repositoryDir = new File(UPLOAD_USER_DIR + File.separator
				+ placeId);

		if (!repositoryDir.exists()) {

			boolean created = repositoryDir.mkdirs();

			if (!created) {
				Response.status(Status.FORBIDDEN).build();
			}
		}

		int num = repositoryDir.list().length;

		String uploadedFileLocation = UPLOAD_USER_DIR + File.separator
				+ placeId + File.separator + num + ".png";

		writeToFile(uploadedInputStream, uploadedFileLocation);
		String output = "File uploaded to : " + uploadedFileLocation;

		Place p = DataServiceFactory.getInstance()
				.getById(placeId, Place.class);
		p.setImageCount(p.getImageCount() + 1);
		DataServiceFactory.getInstance().merge(p);

		Response returnResponse = Response.status(200).entity(output).build();

		return returnResponse;

	}

	@GET
	@Path("{placeId}/{imgCount}")
	@Produces("image/png")
	public Response getFullImage(@PathParam("placeId") Integer placeId,
			@PathParam("imgCount") Integer imgCount) {

		File repositoryFile = getFile(String.valueOf(imgCount), UPLOAD_USER_DIR
				+ File.separator + placeId);
		if (repositoryFile == null || !repositoryFile.exists()) {
			Response returnResponse = Response.noContent()
					.status(Status.NOT_FOUND).build();

			return returnResponse;
		}

		Response returnResponse = returnFile(repositoryFile);

		return returnResponse;

	}

	public static Response returnFile(File file) {
		if (!file.exists()) {
			Response returnResponse = Response.status(Status.NOT_FOUND).build();
			return returnResponse;
		}

		try {
			Date fileDate = new Date(file.lastModified());
			Response returnResponse = Response.ok(new FileInputStream(file))
					.lastModified(fileDate).build();
			return returnResponse;
		} catch (FileNotFoundException e) {

			Response returnResponse = Response.status(Status.NOT_FOUND).build();

			return returnResponse;
		}
	}

	public static File getFile(final String startsWith, String folder) {

		FilenameFilter filter = new FilenameFilter() {

			@Override
			public boolean accept(final File dir, final String name) {

				String removeExt = FilenameUtils.removeExtension(name);
				boolean returnboolean = startsWith.equals(removeExt);
				return returnboolean;
			}
		};

		File f = new File(folder);
		String[] allFiles = f.list(filter);

		if (allFiles != null && allFiles.length > 0) {
			File returnFile = new File(folder + "/" + allFiles[0]);
			return returnFile;
		}

		return null;

	}

	public static void writeToFile(InputStream uploadedInputStream,
			String uploadedFileLocation) {

		try {
			OutputStream out = new FileOutputStream(new File(
					uploadedFileLocation));
			int read = 0;
			byte[] bytes = new byte[1024];

			out = new FileOutputStream(new File(uploadedFileLocation));
			while ((read = uploadedInputStream.read(bytes)) != -1) {
				out.write(bytes, 0, read);
			}
			out.flush();
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}
	//
}
